//--------------------------------------------------------------------------------
// This file is part of the Windows Workflow Foundation Sample Code
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft
// Development Tools and/or on-line documentation.  See these other
// materials for detailed information regarding Microsoft code samples.
// 
// THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//--------------------------------------------------------------------------------

using System;
using System.CodeDom;
using System.ComponentModel.Design.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;

namespace Microsoft.Samples.Workflow.UI
{
    // Custom serializer to properly handle the Transitions property.
    class NavigatorCodeDomSerializer : ActivityCodeDomSerializer
    {
        public NavigatorCodeDomSerializer()
        {
        }

        public override object Serialize(IDesignerSerializationManager manager, object obj)
        {
            if (manager == null)
            {
                throw new ArgumentNullException("manager");
            }
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            Navigator navigator = obj as Navigator;
            if (navigator == null)
            {
                throw new ArgumentException(SR.GetString(SR.Error_UnexpectedArgumentType, typeof(Navigator).FullName), "obj");
            }

            CodeStatementCollection retVal = base.Serialize(manager, navigator) as CodeStatementCollection;
            if (retVal != null)
            {
                foreach (Activity childActivity in navigator.Activities)
                {
                    CodeExpression objectExpression = SerializeToExpression(manager, childActivity);
                    if (objectExpression != null)
                    {
                        TransitionCollection transitions = Navigator.GetTransitions(childActivity) as TransitionCollection;
                        if (transitions.Count > 0)
                        {
                            // We need to add a variable decl in order to make serialization work.
                            CodeExpression param1 = new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(Navigator)), Navigator.TransitionsProperty.Name + "Property");
                            CodeExpression param2 = null;
                            try
                            {
                                ExpressionContext expressionContext = new ExpressionContext(param1, typeof(TransitionCollection), childActivity);
                                manager.Context.Push(expressionContext);
                                param2 = SerializeToExpression(manager, transitions);
                            }
                            finally
                            {
                                manager.Context.Pop();
                            }

                            if (param1 != null && param2 != null)
                            {
                                CodeMethodInvokeExpression codeMethodInvokeExpr = new CodeMethodInvokeExpression(objectExpression, "SetValue", new CodeExpression[] { param1, param2 });
                                retVal.Add(codeMethodInvokeExpr);
                            }
                        }
                    }
                }
            }
            return retVal;
        }
    }
}
